/* eslint-disable array-bracket-spacing */
'use strict';

const assert = require('assert');

const { NumberValue, StringValue } = require('sql-parser').nodes;

const { ExcelColumns } = require('../base_processor');
// const RCMSCategoriesStore = require('../store/rcms_categories_store');
const BSTreeStore = require('../store/bs_tree_store');
// const ColumnStore = require('../store/column_store');
const StringUtil = require('../util/string_util');

const FILTER_MAPPING = require('./filter_mapping');
const SQL_CONDITIONALS = ['AND', 'OR'];

const UN_EXPECTED = Symbol('FilterVisitor#unexpected');

const ACC_FUNDS = [{
  value: '公积金',
  realValue: '住房公积金监管',
}];

class FilterVisitor {
  constructor(excelRows) {
    this.excelRows = excelRows;
    // 预期之外的信息
    this[UN_EXPECTED] = [];
  }

  get unexpected() {
    return this[UN_EXPECTED].filter((ele, pos, arr) => {
      return arr.findIndex(m => m.field === ele.field && m.level === ele.level && m.message === ele.message) === pos;
    });
  }

  async visit(condition) {
    assert(condition, 'condition 不能为空');
    assert(condition.left, 'condition.left 不能为空');
    assert(condition.right, 'condition.right 不能为空');

    // 如果left仍然是一个 condition ,则迭代之
    if (SQL_CONDITIONALS.indexOf(condition.operation.toUpperCase()) >= 0) {
      await this.visit(condition.left);
      await this.visit(condition.right);
    } else {
      await this.visitOperation(condition);
    }
  }

  async visitOperation(operation) {
    switch (operation.left.value) {
      case 'catid':
        await this.visitCateId(operation);
        break;
      case 'profe_type':
        await this.visitProfeType(operation);
        break;
      case 'export':
        await this.visitExport(operation);
        break;
      default:
        await this.visitOther(operation);
    }
  }

  /**
   * 解析cateid查询条件
   * 使用right中的值到
   * @param {Object} operation 操作
   */
  async visitCateId(operation) {
    const left = operation.left;
    const right = operation.right;
    if (!this.preCheckLeft(left)) {
      return;
    }

    if (!right.value) {
      this[UN_EXPECTED].push({
        level: 1,
        filed: left.value,
        message: 'Missing 查询值',
      });
      return;
    }

    operation.left = new StringValue(FILTER_MAPPING[left.value], '');

    const newCateIds = new Set();
    const cateIds = right.value.map(m => m.value);
    for (const cateId of cateIds) {
      const findRow = this.excelRows.find(m => m[ExcelColumns.OLD_COLUMN_ID] === cateId);
      if (!findRow) {
        this[UN_EXPECTED].push({
          level: 2,
          filed: left.value,
          message: `Missing 老栏目(${cateId})`,
        });
      } else {
        if (findRow[ExcelColumns.NEW_COLUMN_ID]) {
          newCateIds.add(findRow[ExcelColumns.NEW_COLUMN_ID]);
        } else {
          this[UN_EXPECTED].push({
            level: 2,
            filed: left.value,
            message: `Missing 新栏目(${cateId})`,
          });
        }
      }
    }
    if (newCateIds.size > 0) {
      right.value = [...newCateIds].map(m => {
        return new NumberValue(m);
      });
    } else {
      // 如果没有一个匹配的，就IN(0)或=0
      right.value = [new NumberValue(0)];
    }
  }

  /**
   * 解析profe_type查询条件
   * LIKE => =
   * 文字 => bs_tree.id
   * @param {Object} operation 操作
   */
  async visitProfeType(operation) {
    const left = operation.left;
    const right = operation.right;
    if (!this.preCheckLeft(left)) {
      return;
    }

    if (!right.value) {
      this[UN_EXPECTED].push({
        level: 2,
        filed: left.value,
        message: 'Missing 查询值',
      });
      return;
    }

    const exactlyRightValue = StringUtil.getRealParentName(right.value.replace(/%/g, ''), ACC_FUNDS);
    const bsTreeList = await BSTreeStore.list();
    const bsTreeOne = bsTreeList.find(m => m.name === exactlyRightValue);
    if (!bsTreeOne) {
      this[UN_EXPECTED].push({
        level: 1,
        filed: left.value,
        message: `NotFound ${right.value}`,
      });
      return;
    }
    operation.left = new StringValue(FILTER_MAPPING[left.value], '');
    right.value = new NumberValue(bsTreeOne.id);
    operation.operation = '=';
  }

  visitOther(operation) {
    const left = operation.left;
    if (!this.preCheckLeft(left)) {
      return;
    }
    operation.left = new StringValue(FILTER_MAPPING[left.value.toString().replace(/`/g, '')], '');
  }

  visitExport(operation) {
    const left = operation.left;
    if (!this.preCheckLeft(left)) {
      return;
    }
    operation.left = '1';
    operation.operation = '=';
    operation.right = '1';
  }

  preCheckLeft(left) {
    if (!FILTER_MAPPING[left.value.toString().replace(/`/g, '')]) {
      this[UN_EXPECTED].push({
        level: 1,
        filed: left.value,
        message: 'Missing 映射关系',
      });
      return false;
    }
    return true;
  }
}

module.exports = FilterVisitor;
